# -*- coding: utf-8 -*-

# from cachesresources import *
#import urllib2想要当雨py3x的import urllib.request
import urllib2
from urllib import urlencode
import zlib
import cookielib
import platform
import os

import dpkt
import pcap
import re
import time
import json

from PyQt4.QtCore import QTextCodec


# -*- coding: utf-8 -*-
__author__ = ""
__copyright__ = ""
__license__ = ""
__version__ = ""
__maintainer__ = ""
__email__ = ""
__status__ = ""

"""
Simple local cache.
It saves local data in singleton dictionary with convenient interface

Examples of use:
    # Initialize
    SimpleCache({'data':{'example':'example data'}})
    # Getting instance
    c = SimpleCache.getInstance()

    c.set('re.reg_exp_compiled',re.compile(r'\W*'))
    reg_exp = c.get('re.reg_exp_compiled',default=re.compile(r'\W*'))

or

    c = SimpleCache.getInstance()
    reg_exp = c.getset('re.reg_exp_compiled',re.compile(r'\W*'))

or
    @scache
    def func1():
        return 'OK'

"""

class SimpleCache(dict):

    def __new__(cls,*args):
        if not hasattr(cls,'_instance'):
            cls._instance = dict.__new__(cls)
        else:
            raise Exception('SimpleCache already initialized')
        return cls._instance

    @classmethod
    def getInstance(cls):
        if not hasattr(cls,'_instance'):
            cls._instance = dict.__new__(cls)
        return cls._instance

    def get(self,name,default=None):
        """Multilevel get function.
        Code:        
        Config().get('opt.opt_level2.key','default_value')
        """
        if not name: 
            return default
        levels = name.split('.')
        data = self            
        for level in levels:
            try:            
                data = data[level]
            except:
                return default

        return data

    def set(self,name,value):
        """Multilevel set function
        Code:        
        Config().set('opt.opt_level2.key','default_value')
        """
        levels = name.split('.')
        arr = self        
        for name in levels[:-1]:
            if not arr.has_key(name):         
                arr[name] = {}   
            arr = arr[name]
        arr[levels[-1]] = value

    def getset(self,name,value):
        """Get cache, if not exists set it and return set value
        Code:        
        Config().getset('opt.opt_level2.key','default_value')
        """
        g = self.get(name)
        if not g:
            g = value
            self.set(name,g)
        return g

def scache(func):
    def wrapper(*args, **kwargs):
        cache = SimpleCache.getInstance()
        fn = "scache." + func.__module__ + func.__class__.__name__ +               func.__name__ + str(args) + str(kwargs)        
        val = cache.get(fn)
        if not val:
            res = func(*args, **kwargs)
            cache.set(fn,res)
            return res
        return val
    return wrapper

def setCache(cachename, cachevalue):#复制缓存
    SimpleCache.getInstance().set(cachename,cachevalue)
    

def getCache(cachename):#缓存中取值
    cachevalue = SimpleCache.getInstance().get(cachename)
    return cachevalue

def deleteCache(casename):
    for cc in SimpleCache.getInstance().keys():
        if str(cc) == str(casename):
            del SimpleCache.getInstance()[str(casename)]


#写入playerheaders配置
def setAllCofig():
    hosts = getCache('hosts') 
    if getCache("cookiess") is not None:
        cookiesss = getCache("cookiess")
    else:
        if os.path.exists('cookies%s%s.txt'%(getCache('servername'),getCache('lbusernamess'))):        
            file = open('cookies%s%s.txt'%(getCache('servername'),getCache('lbusernamess')),'rb')
            cookiesss = str(file.read())
            file.close()
        else:
            cookiesss = ''
    if cookiesss is not None and cookiesss != '[]' and cookiesss != '':
        playerheaders = {
                     'Host':hosts ,
                    'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:31.0) Gecko/20100101 Firefox/31.0',
                    'Accept':'*/*',
                    'Accept-Language':'zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3',
                    'Accept-Encoding':'gzip, deflate',
                    'Referer':'http',
                    'Connection':'keep-alive',
                    'Cookie':cookiesss}
        setCache("playerheaders", playerheaders)
        
#网卡中抓包获取需要的cookies
def get_urlroot_index():
    #coding=utf-8
    try:
        pc=pcap.pcap()  #注，参数可为网卡名，如eth0
    except Exception as e:
        pc=pcap.pcap(name="eth0")
#         pc=pcap.pcap(name="eth0",65535,False,False)
        output = open('error.txt','a')
        output.write('错误'+str(e)+'\n')
        output.close()
    
#     pc=pcap.pcap(name="eth0")       # th1
#     pc.setfilter('tcp port 80')      #  tcp port 80
    pc.setfilter('tcp')      #tcp port 80
#     posting = []
    setAllCofig()
    for p_time, p_data in pc:       
        ret = main_pcap(p_time, p_data)
        if ret:
#             prints(ret)
#             posting.append(ret)
            if ret.split('###')[7] == getCache('hosts') and ret.split('###')[4] == getCache('root') and ret.split('###')[3] == 'POST':
                setCache('ret', ret)
                if getCache('lbusernamess') == '':
                    setCache('cookiess', ret.split('###')[6])
                    if getCache("cookiess") is not None:
                        output = open('cookies%s%s.txt'%(getCache('servername'),getCache('lbusernamess')),'w')
                        output.write(str(getCache("cookiess")))
                        output.close()
                    setAllCofig()
                elif '='+str(getCache('lbusernamess'))+';' in str(ret.split('###')[6]):
                    setCache('cookiess', ret.split('###')[6])
                    if getCache("cookiess") is not None:
                        output = open('cookies%s%s.txt'%(getCache('servername'),getCache('lbusernamess')),'w')
                        output.write(str(getCache("cookiess")))
                        output.close()
                else:
                    setCache('cookiess','')
                setAllCofig()
#                 prints(str(getCache("cookiess")))
#                 print ret.split('###')[6]
#                 print ret
#                 break
#             print(ret) 
                
def main_pcap(p_time, p_data):    
    try:                  # 
        out_format = "%s###%s###%s###%s###%s###HTTP/%s###%s###%s"
        p = dpkt.ethernet.Ethernet(p_data)       
        ret = None
        if p.data.__class__.__name__ == 'IP':
            ip_data = p.data
#             print ip_data
            src_ip = '%d.%d.%d.%d' % tuple(map(ord,list(ip_data.src)))
            dst_ip = '%d.%d.%d.%d' % tuple(map(ord,list(ip_data.dst)))
#             if  p.data.data.__class__.__name__ == 'TCP':
#                 print(ip_data)
            if p.data.data.__class__.__name__=='TCP':
                tcp_data = p.data.data
                if tcp_data.dport==80:
                    if tcp_data.data:
#                         print tcp_data.data
                        h = dpkt.http.Request(tcp_data.data)   # http瑙ｇ爜
                        pre = "^/.*$"
                        cookie = ''
                        host = ''
                        if re.match(pre, h.uri):    
                            http_headers = h.headers
                            host = http_headers['host']
                            url = "http://" + host + h.uri
                            if http_headers.has_key('cookie'):
                                cookie = http_headers['cookie']
                        else:
                            url = h.uri
                        # datetime srcip dstip GET /index.htm HTTP/1.1 cookies  # 杈撳嚭鏃ュ織鏍煎紡
                        ltime=time.localtime(p_time)
                        timeStr=time.strftime("%Y-%m-%d %H:%M:%S", ltime)

                        ret = out_format % (timeStr, src_ip, dst_ip, h.method, url, h.version, cookie, host)
#                         print(ret)
        return(ret)
    except Exception as e:
        aa = 1
#         output = open('error.txt','a')
#         output.write('错误'+str(e)+'\n')
#         output.close()



#打印结果
def prints(content):
    if getCache('tab2') is not None:
        QTextCodec.setCodecForCStrings(QTextCodec.codecForName("utf-8"))
    print content
    
import os.path


#中文转拼音
class PinYin(object):
    def __init__(self, dict_file='word.data'):
        self.word_dict = {}
        self.dict_file = dict_file


    def load_word(self):
        if not os.path.exists(self.dict_file):
            raise IOError("NotFoundFile")

        with file(self.dict_file) as f_obj:
            for f_line in f_obj.readlines():
                try:
                    line = f_line.split('    ')
                    self.word_dict[line[0]] = line[1]
                except:
                    line = f_line.split('   ')
                    self.word_dict[line[0]] = line[1]


#     def hanzi2pinyin(self, string=""):
#         result = []
#         if not isinstance(string, unicode):
#             string = string.decode("utf-8")
#         
#         for char in string:
#             key = '%X' % ord(char)
#             result.append(self.word_dict.get(key, char).split()[0][:-1].lower())
# 
#         return result
    def hanzi2pinyin(self, string=""):
        result = []
        if not isinstance(string, unicode):
            string = string.decode("utf-8")
    
        for char in string:
            key = '%X' % ord(char)
            if not self.word_dict.get(key):
                result.append(char)
            else:
                result.append(self.word_dict.get(key, char).split()[0][:-1].lower())
    
        return result
    def hanzi2pinyin_split(self, string="", split=""):
        result = self.hanzi2pinyin(string=string)
        #if split == "":
        #    return result
        #else:
        return split.join(result)
#     def hanzi2pinyin_split(self, string="", split=""):
#         result = self.hanzi2pinyin(string=string)
#         if split == "":
#             return result
#         else:
#             return split.join(result)

